home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Info 1994 March
/
Internet Info CD-ROM (Walnut Creek) (March 1994).iso
/
networking
/
ip
/
ka9q
/
src890906.arc
/
AX25DUMP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-08-19
|
4KB
|
186 lines
#include <stdio.h>
#include "global.h"
#include "mbuf.h"
#include "ax25.h"
#include "timer.h"
#include "lapb.h"
#include "trace.h"
#include "socket.h"
static char *decode_type __ARGS((int16 type));
/* Dump an AX.25 packet header */
void
ax25_dump(bpp,check)
struct mbuf **bpp;
int check; /* Not used */
{
char tmp[20];
char control,pid,seg;
int16 type;
int unsegmented;
struct ax25 hdr;
struct ax25_addr *hp;
printf("AX25: ");
/* Extract the address header */
if(ntohax25(&hdr,bpp) < 0){
/* Something wrong with the header */
printf(" bad header!\n");
return;
}
pax25(tmp,&hdr.source);
printf("%s",tmp);
pax25(tmp,&hdr.dest);
printf("->%s",tmp);
if(hdr.ndigis > 0){
printf(" v");
for(hp = &hdr.digis[0]; hp < &hdr.digis[hdr.ndigis]; hp++){
/* Print digi string */
pax25(tmp,hp);
printf(" %s%s",tmp,(hp->ssid & REPEATED) ? "*":"");
}
}
if(pullup(bpp,&control,1) != 1)
return;
putchar(' ');
type = ftype(control);
printf("%s",decode_type(type));
/* Dump poll/final bit */
if(control & PF){
switch(hdr.cmdrsp){
case COMMAND:
printf("(P)");
break;
case RESPONSE:
printf("(F)");
break;
default:
printf("(P/F)");
break;
}
}
/* Dump sequence numbers */
if((type & 0x3) != U) /* I or S frame? */
printf(" NR=%d",(control>>5)&7);
if(type == I || type == UI){
if(type == I)
printf(" NS=%d",(control>>1)&7);
/* Decode I field */
if(pullup(bpp,&pid,1) == 1){ /* Get pid */
if(uchar(pid) == PID_SEGMENT){
unsegmented = 0;
pullup(bpp,&seg,1);
printf("%s remain %u",seg & SEG_FIRST ?
" First seg;" : "",seg & SEG_REM);
if(seg & SEG_FIRST)
pullup(bpp,&pid,1);
} else
unsegmented = 1;
switch(uchar(pid)){
case PID_SEGMENT:
printf("\n");
break; /* Already displayed */
case PID_ARP:
printf(" pid=ARP\n");
arp_dump(bpp);
break;
case PID_NETROM:
printf(" pid=NET/ROM\n");
netrom_dump(bpp);
break;
case PID_IP:
printf(" pid=IP\n");
/* Don't verify checksums unless unsegmented */
ip_dump(bpp,unsegmented);
break;
case PID_X25:
printf(" pid=X.25\n");
break;
case PID_TEXNET:
printf(" pid=TEXNET\n");
break;
case PID_NO_L3:
printf(" pid=Text\n");
break;
default:
printf(" pid=0x%x\n",pid);
}
}
} else if(type == FRMR && pullup(bpp,tmp,3) == 3){
printf(": %s",decode_type(ftype(tmp[0])));
printf(" Vr = %d Vs = %d",(tmp[1] >> 5) & MMASK,
(tmp[1] >> 1) & MMASK);
if(tmp[2] & W)
printf(" Invalid control field");
if(tmp[2] & X)
printf(" Illegal I-field");
if(tmp[2] & Y)
printf(" Too-long I-field");
if(tmp[2] & Z)
printf(" Invalid seq number");
printf("\n");
} else
printf("\n");
}
static char *
decode_type(type)
int16 type;
{
switch(uchar(type)){
case I:
return "I";
case SABM:
return "SABM";
case DISC:
return "DISC";
case DM:
return "DM";
case UA:
return "UA";
case RR:
return "RR";
case RNR:
return "RNR";
case REJ:
return "REJ";
case FRMR:
return "FRMR";
case UI:
return "UI";
default:
return "[invalid]";
}
}
/* Return 1 if this packet is directed to us, 0 otherwise. Note that
* this checks only the ultimate destination, not the digipeater field
*/
int
ax_forus(iface,bp)
struct iface *iface;
struct mbuf *bp;
{
struct mbuf *bpp;
char buf[AXALEN];
struct ax25_addr dest,ifcall;
/* Duplicate the destination address */
if(dup_p(&bpp,bp,0,AXALEN) != AXALEN){
free_p(bpp);
return 0;
}
if(pullup(&bpp,buf,AXALEN) < AXALEN)
return 0;
getaxaddr(&dest,buf);
memcpy(&ifcall,iface->hwaddr,AXALEN);
if(addreq(&dest,&ifcall))
return 1;
else
return 0;
}